package ru.mcfr.oxygen.framework.operations.table;

import org.apache.log4j.Logger;
import ro.sync.ecss.extensions.api.*;
import ro.sync.ecss.extensions.api.content.RangeProcessor;
import ro.sync.ecss.extensions.api.node.AttrValue;
import ro.sync.ecss.extensions.api.node.AuthorDocumentFragment;
import ro.sync.ecss.extensions.api.node.AuthorElement;
import ro.sync.ecss.extensions.api.node.AuthorNode;

import javax.swing.text.BadLocationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TableBorderOperation implements AuthorOperation {

    private static Logger logger = Logger.getLogger(TableBorderOperation.class.getName());

    private Map<String, String> parse(String keys, String values, String separator) {

        String[] arKeys = keys.split("\\" + separator);
        String[] arValues = values.split("\\" + separator);
        Map<String, String> map = new HashMap<String, String>();

        int cKeyId = 0;
        for (String cKey : arKeys) {
            String cVal = "";
            if (cKeyId < arValues.length) cVal = arValues[cKeyId];
            if (!cKey.isEmpty())
                map.put(cKey, cVal);
        }

        return map;
    }

    private Map<String, String> parse(String keys, String values) {
        return parse(keys, values, ",");
    }

    private String getBorderInfoForCell(int x, int y) {
        String key = "";

        if (x == 0 & y == 0)
            key = "ltbr";

        if (x == 0 & y > 0)
            key = "tbr";

        if (x > 0 & y == 0)
            key = "lbr";

        if (x > 0 & y > 0)
            key = "br";

        String border = "";

        if (key.contains("l"))
            border += "border-left,";

        if (key.contains("r"))
            border += "border-right,";

        if (key.contains("t"))
            border += "border-top,";

        if (key.contains("b"))
            border += "border-bottom,";

        int size = border.length();
        if (size > 0)
            return border.substring(0, size - 1);
        else
            return "";
    }

    public void doOperation(AuthorAccess authorAccess, ArgumentsMap args) throws IllegalArgumentException, AuthorOperationException {

        AuthorDocumentController controller = authorAccess.getDocumentController();

        String attrValue = "";
        try {
            attrValue = args.getArgumentValue("значение атрибута").toString();
        } catch (Exception e) {
        }
        boolean groupProcessing = false;
        try {
            groupProcessing = args.getArgumentValue("для всех").toString().equals("true");
        } catch (Exception e) {
        }

        try {

            if (groupProcessing) {
                int caretOffset = authorAccess.getEditorAccess().getCaretOffset();
                AuthorNode an = controller.getNodeAtOffset(caretOffset);
                while (!an.getName().equals("таблица"))
                    an = an.getParent();
                AuthorElement ae2 = (AuthorElement) an;

                final String finalAttrValue = attrValue;
                controller.processContentRange(ae2.getStartOffset(), ae2.getEndOffset(), new RangeProcessor() {
                    @Override
                    public void processRange(AuthorDocumentFragment authorDocumentFragment) throws AuthorOperationException, BadLocationException {
                        List<AuthorNode> tables = authorDocumentFragment.getContentNodes();
                        for (AuthorNode table : tables){
                            AuthorElement eTable = (AuthorElement) table;
                            eTable.removeAttribute("border-left");
                            eTable.removeAttribute("border-right");
                            eTable.removeAttribute("border-top");
                            eTable.removeAttribute("border-bottom");

                            List<AuthorNode> rows = eTable.getContentNodes();
                            int rowspan = 0;
                            int realRow = 0;
                            boolean isRowspan;
                            for (int r = 0; r < rows.size(); r++){
                                if (rows.get(r).getName().equals("строка")){
                                    List<AuthorNode> cells = ((AuthorElement) rows.get(r)).getContentNodes();
                                    for (int c = 0; c < cells.size(); c++){
                                        AuthorElement cell = (AuthorElement) cells.get(c);
                                        cell.removeAttribute("border-left");
                                        cell.removeAttribute("border-right");
                                        cell.removeAttribute("border-top");
                                        cell.removeAttribute("border-bottom");

                                        if (!finalAttrValue.equals("remove")) {
                                            int realCol = c;
                                            if (c == 0) {

                                                try {
                                                    rowspan = Integer.valueOf(cell.getAttribute("rowspan").getValue()) - 1;
                                                    isRowspan = true;
                                                } catch (Exception e) {
                                                    isRowspan = false;
                                                }

                                                if (rowspan > 0 & !isRowspan) {
                                                    rowspan--;
                                                    realCol = c + 1;
                                                }
                                            }

                                            if (realRow == 0 & realCol == 0) {
                                                cell.setAttribute("border-left", new AttrValue("1px solid #000000"));
                                                cell.setAttribute("border-right", new AttrValue("1px solid #000000"));
                                                cell.setAttribute("border-top", new AttrValue("1px solid #000000"));
                                                cell.setAttribute("border-bottom", new AttrValue("1px solid #000000"));
                                            } else if (realRow == 0 & realCol > 0) {
                                                cell.setAttribute("border-right", new AttrValue("1px solid #000000"));
                                                cell.setAttribute("border-top", new AttrValue("1px solid #000000"));
                                                cell.setAttribute("border-bottom", new AttrValue("1px solid #000000"));
                                            } else if (realRow > 0 & realCol == 0) {
                                                cell.setAttribute("border-left", new AttrValue("1px solid #000000"));
                                                cell.setAttribute("border-right", new AttrValue("1px solid #000000"));
                                                cell.setAttribute("border-bottom", new AttrValue("1px solid #000000"));
                                            } else if (realRow > 0 & realCol > 0) {
                                                cell.setAttribute("border-right", new AttrValue("1px solid #000000"));
                                                cell.setAttribute("border-bottom", new AttrValue("1px solid #000000"));
                                            }
                                        }

                                    }
                                    realRow++;
                                }
                            }
                        }
                    }
                });

                authorAccess.getEditorAccess().setCaretPosition(caretOffset);

            }
        } catch (BadLocationException e1) {
            authorAccess.getWorkspaceAccess().showErrorMessage("Ошибка вставки/редактирования элемента:" + e1.getMessage());
        }

    }

    public ArgumentDescriptor[] getArguments() {
        ArgumentDescriptor[] res = {
                new ArgumentDescriptor("атрибут", ArgumentDescriptor.TYPE_STRING, ""),
                new ArgumentDescriptor("значение атрибута", ArgumentDescriptor.TYPE_STRING, ""),
                new ArgumentDescriptor("применить для тэга", ArgumentDescriptor.TYPE_STRING, ""),
                new ArgumentDescriptor("для всех", ArgumentDescriptor.TYPE_STRING, "true/false"),
        };
        return res;
    }

    public String getDescription() {
        return "Универсальная функция для работы с атрибутами";
    }

}
